package com.dycong.common.network;

import com.dycong.common.IOutil.IOUtil;
import com.dycong.common.common.ApplicationConfig;
import com.dycong.common.common.StringUtil;
import lombok.extern.log4j.Log4j;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by dycong on 16-3-25.
 */
@Log4j
public class InteractRichStateHttpClient implements RichStateHttpClient {

    String appKey;
    String appCode;

    public InteractRichStateHttpClient(String appKey, String appCode) {
        this.appKey = appKey;
        this.appCode = appCode;
    }

    RichStateHttpClient delegate = RichStateHttpClientImpl.getInstance();

    Map<String, String> genSignatureMap(String content) {
        Map<String, String> signatureMap = new HashMap<>();
        String timestamp = System.currentTimeMillis() + "";
        signatureMap.put("appKey", appKey);
        signatureMap.put("timestamp", timestamp);
        String forMd5 = content + timestamp + appCode;
        log.debug("for MD5: " + forMd5);
        signatureMap.put("signature", StringUtil.getMd5HexByUtf8Encoding(forMd5));
        return signatureMap;
    }


    Map<String, String> prepare(Map<String, String> headerMap, Map<String, String> param, String encoding) {
        try {
            String content = param == null ? "" :
                    IOUtil.toString(AbstractHttpClient.mapToRequestEntity(param, encoding).getContent(), encoding);
            if (headerMap == null) {
                headerMap = genSignatureMap(content);
            } else {
                headerMap.putAll(genSignatureMap(content));
            }
            return headerMap;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public RichStateHttpClientImpl.Result doGet(String url, String encoding, Map<String, String> header, Map<String, String> body) {
        header = prepare(header, body, encoding);
        return delegate.doGet(url, encoding, header, body);
    }

    @Override
    public RichStateHttpClientImpl.Result doPost(String url, String encoding, Map<String, String> headerMap, Map<String, String> paramMap) {
        headerMap = prepare(headerMap, paramMap, encoding);
        return delegate.doPost(url, encoding, headerMap, paramMap);
    }

    @Override
    public RichStateHttpClientImpl.Result postJson(String url, String encoding, Map<String, String> headerMap, String json) {
        if (headerMap == null) {
            headerMap = genSignatureMap(json);
        } else {
            headerMap.putAll(genSignatureMap(json));
        }
        Result result = delegate.postJson(url, encoding, headerMap, json);
        if (result.getContent().length() > 8000) {
            log.debug("response content too long, may not have signature header, ignore check header");
        } else {
            if (ApplicationConfig.getBoolean("checkResponseSignature").orElse(false)) {
                String signature = result.getResponseHeader().get("signature").get(0);
                log.debug("signature: " + signature);
                String md5 = StringUtil.getMd5Hex((result.getContent() + appCode).getBytes());
                log.debug("md5      : " + md5);
                if (!md5.equalsIgnoreCase(signature)) {
                    //签名不正确
                    throw new RuntimeException("response signature incorrect");
                }
            }
        }
        return result;
    }


}
